package com.lagou.protocol.decoder;

import com.lagou.protocol.serializer.Serializer;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;

/**
 * RPC解码器
 */
public class RpcDecoder extends ByteToMessageDecoder {
    /**
     * 目标类
     */
    private Class<?> clazz;

    /**
     * 序列化器
     */
    private Serializer serializer;

    /**
     * 构造RpcDecoder对象
     *
     * @param clazz 目标类
     * @param serializer 序列化器
     */
    public RpcDecoder(Class<?> clazz, Serializer serializer) {
        this.clazz = clazz;
        this.serializer = serializer;
    }

    /**
     * 解码给定的消息
     *
     * @param channelHandlerContext 处理器上下文
     * @param byteBuf 给定的消息
     * @param list 解码后的消息
     * @throws Exception
     */
    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
        int readableBytes = byteBuf.readableBytes();
        if (readableBytes < 4) {
            return;
        }

        byteBuf.markReaderIndex();

        int length = byteBuf.readInt();
        if (readableBytes < (length + 4)) {
            byteBuf.resetReaderIndex();
            return;
        }

        byte[] bytes = new byte[length];
        byteBuf.readBytes(bytes);

        Object obj = serializer.deserialize(clazz, bytes);
        list.add(obj);
    }
}
